package com.rosh.rpc.core.netty.handler;

import com.rosh.rpc.core.data.RpcRequest;
import com.rosh.rpc.core.data.RpcResponse;
import com.rosh.rpc.core.spring.SpringBeanFactory;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Method;

/**
 * @Description:
 * @Author: rosh
 * @Date: 2022/6/12 22:42
 */
@Slf4j
public class RpcRequestHandler extends SimpleChannelInboundHandler<RpcRequest> {


    @Override
    protected void channelRead0(ChannelHandlerContext ctx, RpcRequest rpcRequest) {

        log.info("RpcRequestHandler 收到请求:{}", rpcRequest);

        RpcResponse response = new RpcResponse();
        response.setRequestId(rpcRequest.getRequestId());

        //获取信息
        //接口名称
        String className = rpcRequest.getClassName();
        //方法名称
        String methodName = rpcRequest.getMethodName();
        //参数类型
        Class<?>[] parameterTypes = rpcRequest.getParameterTypes();
        //参数
        Object[] parameters = rpcRequest.getParameters();

        try {
            //找到目标bean
            Object targetBean = SpringBeanFactory.getBean(Class.forName(className));
            Method targetMethod = targetBean.getClass().getMethod(methodName, parameterTypes);
            //执行目标方法获取结果
            Object result = targetMethod.invoke(targetBean, parameters);
            //封装响应结果
            response.setResult(result);
        } catch (Throwable e) {
            response.setCause(e);
            log.error("rpc server invoke error", e);
        } finally {
            log.info("服务端执行成功，响应为:{}", response);
            ctx.channel().writeAndFlush(response);
        }

    }


    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.error("服务端出现异常.", cause);
        super.exceptionCaught(ctx, cause);
    }
}
